home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 3
/
Gold Medal Software - Volume 3 (Gold Medal) (1994).iso
/
utils2
/
mymous12.arj
/
KNOBS.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-02-12
|
9KB
|
337 lines
; KNOBS
; Andrew Forrest
; Started 6 January 1994
; $VER: Knobs.asm 1.0 (12.02.94)
; Assembled with DEVPAC 3.02
nolist
; Starting from V36, the Amiga OS has several bit switches embedded in
; various control structures. Several programs allow the user to alter these
; settings, including my mouse-accelerator/swiss-army-knife program MyMouse.
; I didn't like having all of these switch options in MyMouse, especially
; since there were several other switches I could think of adding, so I have
; split these extra options off into a seperate program--KNOBS!
include everything.i
Execbase equ 4
;*╗╗ Code entrypoint
;*╗╗ Allocate global memory for variables
MAIN: move.l Execbase,a6
moveq #Globals_SIZEOF,d0
move.l #MEMF_CLEAR,d1
just AllocMem
tst.l d0
beq Unhappy
move.l d0,a5
move.l a6,execbase(a5) ; Cache local (fast?) copy of execbase
;*╗╗ Open the DOS library
lea dosname(pc),a1
moveq #0,d0 ; Open any version
just OpenLibrary
move.l d0,dosbase(a5)
beq Unhappy
;*╗╗ Open the utility library
moveq #msg_NoUtility,d7
lea utilityname(pc),a1
moveq #37,d0
just OpenLibrary
move.l d0,utilitybase(a5)
beq Error
moveq #msg_OldDos,d7
move.l dosbase(a5),a6
cmp.w #36,LIB_VERSION(a6) ; Need at least V36 DOS for
blo Error ; command-line parsing
lea Template(pc),a0
move.l a0,d1
lea Options(a5),a0
move.l a0,d2
moveq #0,d3
moveq #msg_NoArgs,d7
just ReadArgs
move.l d0,RdArgs(a5)
beq Error
;*╗╗ Handle 'STAR' option.
move.l WildStarOption(a5),d1
beq.s .NoStar
move.l dosbase(a5),a0
move.l dl_Root(a0),a0 ; (a6==dosbase(a5))
lea rn_Flags(a0),a0
moveq #0,d0
move.l d1,a1
bsr StringBit
.NoStar
;*╗╗ Perform NoClick, if desired.
; (d2=charflag;d3=unit#;d4=^MsgPort;a2=argument;a3=^IORequest)
move.l execbase(a5),a6
move.l NoClickOption(a5),d0
beq .NoNoClick
move.l d0,a2
;*╗╗ Create an IORequest structure
just CreateMsgPort
move.l d0,d4 ; MsgPort in d4
beq .NoNoClick
move.l d4,a0
moveq #IOSTD_SIZE,d0
just CreateIORequest
tst.l d0
beq.s .fail
move.l d0,a3 ; IORequest in a3
moveq #-1,d3
.ClickLoop addq.l #1,d3 ; Count trackdisk units
move.b (a2)+,d2 ; Get next character of flag string
beq.s .endloop ; Quit on string null-terminator
lea TrackName(pc),a0 ;device name
move.l d3,d0 ;unit number
lea (a3),a1 ;IO request
moveq.l #0,d1 ;flags
just OpenDevice
tst.l d0
bne.s .ClickLoop
move.l IO_UNIT(a3),a0
lea TDU_PUBFLAGS(a0),a0
moveq #TDPB_NOCLICK,d0
move.b d2,d1
bsr CharBit
lea (a3),a1
just CloseDevice
bra.s .ClickLoop
.endloop lea (a3),a0
just DeleteIORequest
.fail move.l d4,a0
just DeleteMsgPort
.NoNoClick
;*╗╗ Border-blanking option.
tst.l BorderBlankOption(a5)
beq.s .NoBBlank
moveq #msg_BBlankGfx,d7
lea gfxname(pc),a1
moveq #39,d0
syscall OpenLibrary
move.l d0,graphicsbase(a5)
beq Error
move.l d0,a0
lea gb_BP3Bits(a0),a0
moveq #5,d0
move.l BorderBlankOption(a5),a1
bsr StringBit
moveq #msg_BBlankInt,d7
lea intname(pc),a1
moveq #33,d0
just OpenLibrary
move.l d0,intuitionbase(a5)
beq.s Error
intcall RemakeDisplay
.NoBBlank
;*╗╗ Alert-timer option.
move.l AlertTimerOption(a5),d0
beq.s .NoAlertTimer
moveq #msg_ATiOldExec,d7
move.l d0,a0
move.l (a0),d0
move.l execbase(a5),a0
cmp.w #39,LIB_VERSION(a0)
blo.s Error
move.l d0,LastAlert+3*4(a0)
.NoAlertTimer
Satisfied: moveq #RETURN_OK,d0 ; Assume a happy ending
bra.s Deallocate
Unhappy: moveq #RETURN_FAIL,d0 ; Or maybe not
; Jump to this routine with d0=Returncode
Deallocate: push.l d0
move.l a5,d0
beq.s .nothing ; Global structure not even there
tst.l dosbase(a5)
beq.s .no_dos ; Got to check, since we're _calling_ dos
move.l RdArgs(a5),d1
doscall FreeArgs ; Does nothing if passed NULL
.no_dos lea LibraryBases(a5),a2
move.l execbase(a5),a6
moveq #NumLibraries-1,d2
.librryloop move.l (a2)+,a1
just CloseLibrary ; Does nothing if passed NULL
dbra d2,.librryloop
lea (a5),a1
moveq #Globals_SIZEOF,d0
just FreeMem
.nothing pop.l d0 ; Get RETURN_ code back and...
rts ; Return to DOS
;***************************************************************************
;** Error conditions
; Branch to here on error condition with d7=errn
Error: move.w ErrorTable(pc,d7.w),d7
lea ErrorTable(pc,d7.w),a0
bsr Message
bra Unhappy
errn set 0
Err macro ; Message-tag
dc.w _\1-ErrorTable ;The error-message-table-entry
msg_\1 equ errn ; The identifier (offset) for that entry
errn set errn+2 ; Next table offset
endm
ErrorTable: Err OldDos
Err NoUtility
Err NoArgs
Err BBlankGfx
Err BBlankInt
Err ATiOldExec
_OldDos dc.b "You need Release 2 of AmigaDOS to use this program.",0
_NoUtility dc.b "Can't open utility.library V37.",0
_NoArgs dc.b "Unable to read command-line arguments.",0
_BBlankGfx dc.b "Can't open graphics.library V39 for the BORDERBLANK option.",0
_BBlankInt dc.b "Can't open intuition.library for the BORDERBLANK option.",0
_ATiOldExec dc.b "You need Release 3 to use the ALERTTIMER option.",0
even
;***************************************************************************
;***************************************************************************
;** Useful routines
; Print out the name of the program, colon, null-term string and end-of-line.
; Takes a0=^string\0; a5=^Globals (with dosbase); Returns, Trashes nil;
Message:
pushm.l a0-a2/a6/d0-d4
lea (a0),a2 ; Store stringpointer for safe-keeping
doscall Output ; \ Get the output channel
move.l d0,d4 ; / And store in d4
move.l d4,d1
lea ProgramName(pc),a0
move.l a0,d2
moveq #NameLength,d3
just Write ; Write the header: "KNOBS: "
move.l d4,d1
move.l a2,d2
moveq #-1,d3 ; Assume string of zero length
.loop addq.l #1,d3 ; ...add one to length
tst.b (a2)+ ; ...test for null
bne.s .loop ; ...and exit loop when we get it
just Write ; Write out this string
move.l d4,d1
lea CarriageReturn(pc),a0
move.l a0,d2
moveq #1,d3
just Write ; Write out the Carriage-Return
popm.l a0-a2/a6/d0-d4
rts
ProgramName: dc.b "KNOBS: "
NameLength equ *-ProgramName
CarriageReturn: dc.b 10
; Uses Bit to change a bit based on a string which contains "ON", "OFF" or
; "CHANGE"--any other string has no effect. Uses utility library to do a
; case-insensitive string comparison.
; Takes a0=^flags; d0=bit#; a1=^string; Returns, Trashes nothing.
; Uses a2=^search string; d2=loopcounter=[CHANGE,OFF,ON]; d3=str offset;
StringBit: push.w d1
pushm.l a0-a3/a6/d0/d2-d3
move.l utilitybase(a5),a6
lea (a1),a2 ; Store user string for safekeeping
moveq #0,d3 ; Clear top of d3
moveq #3,d2 ; Initialise loopcounter==codenumber
.loop lea (a2),a0 ; String supplied by user
move.b Table-1(pc,d2.w),d3 ; Look up offset from table
lea Table(pc,d3.w),a1 ; Obtain string from offset
just Stricmp ; Compare the two strings
tst.l d0
dbeq d2,.loop ; Loop until match or counter reaches -1
.endloop move.b d2,d1
popm.l a0-a3/a6/d0/d2-d3
bsr.s Bit
pop.w d1
rts
Table: dc.b On-Table,Off-Table,Change-Table
On dc.b "ON",0
Off dc.b "OFF",0
Change dc.b "CHANGE",0
even
; Changes a bit based on a single character, d1, which is `1' (SET), `0'
; (CLEAR), `*' (CHANGE) or `-' (IGNORE).
; Takes a0=^flags; d0=bit#; d1.b=character; Trashes, returns nothing.
CharBit: pushm.l a1/d2
lea CharTable(pc),a1
moveq #3,d2
.loop cmp.b (a1)+,d1
dbeq d2,.loop ; Keep looping til char=d1 or count=-1
.endloop move.b d2,d1
bsr.s Bit
popm.l a1/d2
rts
CharTable: dc.b "*01-"
; (Possibly) changes a bit in a memory location based on whether d1
; is BITSET=1, BITCLEAR=2, BITCHANGE=3 or BITIGNORE=anything else.
; Takes a0=^flags; d0=bit#; d1.b=action; Returns & trashes nothing.
Bit: push.w d1
subq.b #1,d1
bne.s .noset ; IF d1==BITSET THEN
.set bset d0,(a0) ; set
bra.s .end ; ELSE
.noset subq.b #1,d1
bne.s .noclear ; IF d1==BITCLEAR THEN
.clear bclr d0,(a0) ; clear
bra.s .end ; ELSE
.noclear subq.b #1,d1
bne.s .end ; IF d1==BITCHANGE THEN
.change bchg d0,(a0) ; change
.end pop.w d1 ; ENDIF
rts
;***************************************************************************
;** Static data
dc.b "$VER: Knobs 1.0 (06.02.94)"
dosname dc.b "dos.library",0
gfxname dc.b "graphics.library",0
intname dc.b "intuition.library",0
utilityname dc.b "utility.library",0
TrackName: dc.b "trackdisk.device",0
;***************************************************************************
; Structure of global data area
STRUCTURE Globals,0
APTR execbase
LABEL LibraryBases
APTR dosbase
APTR graphicsbase
APTR intuitionbase
APTR utilitybase
LABEL EndLibs
NumLibraries equ (EndLibs-LibraryBases)/4
APTR RdArgs
LABEL Options
LONG AlertTimerOption
LONG BorderBlankOption
LONG NoClickOption
LONG WildStarOption
LABEL Globals_SIZEOF
Template: dc.b "ALERTTIMER/K/N,"
dc.b "BBLANK=BORDERBLANK/K,"
dc.b "NOCLICK=NODISKCLICK/K,"
dc.b "STAR=WILDSTAR/K"
dc.b 0